
#include "evalsoc.h"
#include "evalsoc_uart.h"

#define PCLKFREQ                (50 * 1000000)
#define BAUD_RATE(n)            (PCLKFREQ / (n) / 16)

int32_t uart_init( dw_uart_regs_t * puart, uint32_t baudrate)
{
    if (__RARELY(puart == NULL)) {
        return -1;
    }


    /* DLAB = 1  */
    puart->LCR = 0x83;
  
    /* Set DLL for baudrate */
    puart->DLL = BAUD_RATE(115200) & 0xff;
    puart->DLH = (BAUD_RATE(115200) >> 8) & 0xff;

    /* DLAB = 0, LCR: Length 8, no parity, 1 stop bit. */
    puart->LCR = 0x03;

    /* IER to */
    puart->IER = 0x80;
    
    /* FCR: Enable FIFO, reset TX and RX. */
    puart->FCR = 0x97;
    return 0;
}


int32_t uart_write( dw_uart_regs_t * puart, uint8_t val )
{
    if (__RARELY(puart == NULL)) {
        return -1;
    }

    while ( (puart->LSR & 0x20) == 0 ) {
        __NOP();
    }
    
    /**/
    puart->THR = (uint32_t)val;
    return 0;
}


uint8_t uart_read( dw_uart_regs_t * puart )
{

    if (__RARELY(puart == NULL)) {
        return -1;
    }

    /**/
    while ( (puart->LSR & 0x1) == 0 ) {
        __NOP();
    }

    return (uint8_t)( puart->RBR );
}


/*
非阻塞.
返回值 < 0 表示没有字符.
*/
int uart_try_getch( dw_uart_regs_t * puart )
{
    if ( (puart->LSR & 0x1) == 0 ) {
        return -1;
    } else {
        return (uint8_t)( puart->RBR );
    }
}



